import {
  getAllOrgAPI,
  listRoleAPI,
  getAllUserGroupAPI,
  getActiveUserAPI,
  getInvalidUserAPI,
} from '@/services/organization';
import { getImageById, initParams } from '@/utils/utils';
import { setOrganization, getOrganizationInfo, organizationDB } from '@/utils/organization';
import type { UserInfoProp } from '@/utils/organization';
import { setUser } from '@/utils/user';
import { setRole } from '@/utils/role';
import { setUserGroup } from '@/utils/usergroup';
import type { Model } from './connect';
import { isEmpty } from 'lodash';

interface Param {
  filterInfo: {
    filterModel: boolean;
    [prop: string]: any;
  };
  pageInfo: any;
}

interface Org {
  id: string;
  fullOrgId: string;
  fullOrgName: string;
  orgCode: string;
  orgName: string;
  orgType: string;
}

interface Role {
  id: string;
  roleCode: string;
  roleName: string;
}
interface UserGroup {
  id: string;
  fullGroupId: string;
  groupCode: string;
  groupName: string;
}

export const formatParamsUserRole: (obj: { page: number; pageSize: number; [p: string]: any }) => Param = (
  { page, pageSize, ...restParams } = {} as any,
) => {
  return {
    filterInfo: {
      filterModel: true,
      ...restParams,
    },
    pageInfo: {
      pageSize,
      beginIndex: (page - 1) * pageSize,
    },
  };
};

const cacheKey = 'invalidUser';
const initialState = {
  organizations: {},
  users: {},
  userGroups: {},
  roles: {},

  listOrganizations: [],
  listUsers: [],
  listUserGroups: [],
  listRoles: [],
};

export type OrganizationState = Readonly<typeof initialState>;

interface Organization extends Model {
  state: OrganizationState;
}

const OrganizationModel: Organization = {
  namespace: 'organization',
  state: initialState,
  effects: {
    *fetchAllOrg(action, { put }) {
      yield put({ type: 'fetchOrg' });
      yield put({ type: 'fetchAllUser' });
      yield put({ type: 'fetchAllRole' });
      // yield put({ type: 'fetchAllUserGroup' });
    },
    //获取所有组织信息(平铺)
    *fetchOrg(action, { call, put }) {
      try {
        const listOrganizations = yield call(getAllOrgAPI);

        yield put({
          type: 'save',
          payload: { listOrganizations },
        });
        const organizations = listOrganizations.reduce((merged: object, cur: Org) => {
          setOrganization({
            id: cur.id,
            data: cur,
          }); // 缓存到utils 以便脱离modle使用
          return Object.assign(merged, { [cur.id]: cur });
        }, {});
        yield put({
          type: 'save',
          payload: { organizations },
        });
        return true;
      } catch (err) {
        console.error(err);
        return false;
      }
    },
    *fetchAllUser(_, { call, put }) {
      try {
        let listUsers: any[] = [];
        const userCache = yield organizationDB.getItem(cacheKey);
        if (!isEmpty(userCache)) {
          listUsers = userCache;
        } else {
          listUsers = yield call(getInvalidUserAPI);
          organizationDB.setItem(cacheKey, listUsers, 24 * 60 * 60 * 3);
        }
        //如果indexDb里没有用户信息就调用接口
        if (true) {
          const activeUsers = yield call(getActiveUserAPI);
          listUsers = listUsers.concat(activeUsers);
        } else {
          //如果有就直接拿出来
          listUsers = yield organizationDB.getTableList(organizationDB.users);
        }
        //先把用户数组存到model
        yield put({
          type: 'save',
          payload: { listUsers },
        });
        //存缓存，
        const users = listUsers.reduce((merged: object, cur: UserInfoProp) => {
          // 将组织用户的所属组织信息关联起来
          cur.orgInfo = getOrganizationInfo(cur.organizationId);
          cur.orgName = cur.orgInfo.orgName;
          //头像
          if (cur.pictureId) cur.avatarUrl = getImageById(cur.pictureId);
          // 缓存到utils 以便脱离modle使用
          setUser({
            id: cur.id,
            userLoginName: cur.userLoginName,
            data: cur,
            initial: true,
          });
          return Object.assign(merged, { [cur.id]: cur });
        }, {});

        yield put({
          type: 'save',
          payload: { users },
        });
      } catch (err) {
        console.error(err);
      }
    },
    *fetchAllRole(action, { call, put, select }) {
      const params = { page: 1, pageSize: 500 };
      const newsParams = Object.assign({}, initParams, formatParamsUserRole(params));
      const response = yield call(listRoleAPI, {
        data: newsParams,
        serviceId: 'fwSecurity',
      });
      yield put({
        type: 'save',
        payload: { listRoles: response.content },
      });
      const roles = response.content.reduce((merged: object, cur: Role) => {
        setRole({
          id: cur.id,
          data: cur,
        }); // 缓存到utils 以便脱离modle使用
        return Object.assign(merged, { [cur.id]: cur });
      }, {});
      yield put({
        type: 'save',
        payload: { roles },
      });
    },
    *fetchAllUserGroup(action, { call, put }) {
      const response = yield call(getAllUserGroupAPI);
      yield put({
        type: 'save',
        payload: { listUserGroups: response },
      });
      const userGroups = response.reduce((merged: object, cur: UserGroup) => {
        setUserGroup({
          id: cur.id,
          data: cur,
        }); // 缓存到utils 以便脱离modle使用
        return Object.assign(merged, { [cur.id]: cur });
      }, {});
      yield put({
        type: 'save',
        payload: { userGroups },
      });
    },
  },
  reducers: {
    save(state, { payload }: any) {
      return {
        ...state,
        ...payload,
      };
    },
  },
};

export default OrganizationModel;
